﻿using UnityEngine;
using UnityEngine.Tilemaps;

/* 
 * 自定义砖块实现，参照官方 Tile 的实现方法：
 * https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/Tilemap/Managed/Tile.cs
 * GetTileData() 和 RefreshTile() 可以不用实现
 */
namespace SLG_Demo_0
{
	/// <summary>
	/// 地图格子绘制时的类型
	/// </summary>
	public enum ECellDisplayType
	{
		DynamicBegin,	// === 动态类型 Begin，用来分界用。本身无意义 ===
		Normal,			//普通
		Selected,		//只是被选中
		Start,			//寻路的起点
		End,			//寻路的重点
		Path,           //寻路结果经过
		PathAtStatic,   //寻路结果经过，和静态地形叠加
		Searched,		//被搜索过的
		Range,			//范围
		DynamicEnd,		// === 动态类型 End，用来分界用。本身无意义 ===

		StaticBegin,	// === 静态类型 Begin，用来分界用。本身无意义 ===
		Obstacle,		// 障碍，无法通过。对应 ECellDataType.Obstacle
		Swamp,          // 沼泽，影响行进速度。对应 ECellDataType.Swamp
		StaticEnd,		// === 静态类型 End，用来分界用。本身无意义 ===
	}

	/// <summary>
	/// 地图单元格显示
	/// </summary>
	public class CellDisplay : Tile
	{
		/// <summary>
		/// 所属地图对象
		/// </summary>
		private MapObject m_pMapObject = null;

		/// <summary>
		/// 当前地图格子显示类型
		/// </summary>
		private ECellDisplayType m_DisplayType;

		/// <summary>
		/// 当前地图格子在大地图上的横坐标
		/// </summary>
		private int m_Row;

		/// <summary>
		/// 当前地图格子在大地图上的纵坐标
		/// </summary>
		private int m_Col;


		public CellDisplay()
		{
			color = Color.white;
			transform = Matrix4x4.identity;
			flags = TileFlags.LockColor;
			colliderType = ColliderType.Sprite;
		}

		/// <summary>
		/// 初始化对象，由于采用 ScriptableObject.CreateInstance() 方式创建故无法调用默认构造函数
		/// </summary>
		/// <param name="nRow"></param>
		/// <param name="nCol"></param>
		/// <param name="rSprite"></param>
		public void Create(MapObject pMapObj, int nRow, int nCol, Sprite rSprite)
		{
			//base.colliderType = Tile.ColliderType.Sprite;
			//base.flags = TileFlags.LockColor;
			//base.transform = Matrix4x4.identity;
			//m_Color = Color.white;
			//base.sprite = sprite;

			m_pMapObject = pMapObj;
			sprite = rSprite;
			m_DisplayType = ECellDisplayType.Normal;
			m_Row = nRow;
			m_Col = nCol;

			// 在内存中创建预设体 go，显示颜色
			//GameObject go = new GameObject();
			//go.name = "prefab_cellpos";
			//go.transform.localScale = new Vector3(5.0f, 5.0f, 5.0f);

			RefreshColor();
		}

		public void SetSprite(Sprite rSprite)
		{
			sprite = rSprite;
		}

		/// <summary>
		/// 获取当前格子显示层 CellDisplay 上的数据。
		/// 由于 CellDisplay 没有包含 CellData，只能通过 MapData 取（未确定？）
		/// 增加一个方便调用的接口
		/// </summary>
		public CellData GetData()
		{
			return m_pMapObject.MapData.Cells[m_Row, m_Col];
		}

		public int X
		{
			get
			{
				return m_Row;
			}
		}

		public int Y
		{
			get
			{
				return m_Col;
			}
		}

		public ECellDisplayType DisplayType
		{
			get
			{
				return m_DisplayType;
			}

			set
			{
				m_DisplayType = value;
				RefreshColor();
			}
		}

		public bool IsDynamicType()
		{
			return DisplayType > ECellDisplayType.DynamicBegin && DisplayType < ECellDisplayType.DynamicEnd;
		}

		public bool IsStaticType()
		{
			return DisplayType > ECellDisplayType.StaticBegin && DisplayType < ECellDisplayType.StaticEnd;
		}

		/// <summary>
		/// 刷新地图格子颜色
		/// </summary>
		public void RefreshColor()
		{
			switch (m_DisplayType)
			{
				case ECellDisplayType.Normal:
					color = Color.white;
					return;
				case ECellDisplayType.Start:
					color = Color.red;
					return;
				case ECellDisplayType.Selected:
					color = Color.red;
					return;
				case ECellDisplayType.End:
					color = Color.blue;
					return;
				case ECellDisplayType.Path:
					color = Color.yellow;
					return;
				case ECellDisplayType.PathAtStatic:
					color = Color.cyan;//TODO：应换一种颜色，和 Searched, Range 分开
					return;
				case ECellDisplayType.Searched:
					color = Color.cyan;
					return;
				case ECellDisplayType.Range:
					color = Color.cyan;
					return;
				case ECellDisplayType.Obstacle:
					color = Color.gray;
					return;
				case ECellDisplayType.Swamp:
					color = new Color(128.0f, 0.0f, 255.0f);
					return;
				default:
					break;
			}
		}

		public void OnMouseClk()
		{
		}

		//public override bool Equals(CellDisplay other)
		public bool Equals(CellDisplay other)
		{
			if (base.gameObject.GetInstanceID() == other.gameObject.GetInstanceID() && X == other.X && Y == other.Y)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
		{
			base.GetTileData(position, tilemap, ref tileData);
		}

		public override void RefreshTile(Vector3Int position, ITilemap tilemap)
		{
			tilemap.RefreshTile(position);
		}
	}
}
